/**
     * 对象池泛型
     */
export class ObjPool<T> {
    /** 数据类型 */
    protected objType;
    /** 对象池 */
    protected pool = [];
    /** 对象计数 */
    public objCount: number = 0;
    /** 初始化数量 */
    protected initNum: number = 0;
    /** 是否需要预填充对象 */
    protected poolMinSize: number = 0;
    /** 对象数量上限 */
    protected poolMaxSize: number = 50;

    public constructor(c: new () => T, maxSize = 100000) {
        this.objType = c;
        this.pool.length = 0;
        this.poolMaxSize = maxSize
    }

    /**
     * 初始化
     * @param initNum 初始加载对象数
     * @param minSize 对象池最少对象数
     * @param maxSize 对象池最大对象数
     * maxSize一定大于minSize minSize最小为0
     */
    public init(initNum: number = 0, minSize: number = 0, maxSize: number = 50) {
        this.poolMinSize = Math.min(0, minSize);
        this.poolMaxSize = Math.max(maxSize, this.poolMinSize);
        this.preLoadObj(initNum);
    }

    /**
     * 回收
     */
    public put(obj: T) {
        this.pool.push(obj);
        if (this.objCount > this.poolMaxSize) {
            this.pool.unshift();
            return;
        }
        this.objCount++;
    }

    /**
     * 取对象
     */
    public get(): T {
        if (this.objCount <= this.poolMinSize) {
            this.preLoadObj(this.poolMinSize)
        }
        this.objCount--;
        let item = this.pool.pop();
        // 这里再拿出的时候判断对象是否实现了IObjectReset接口，应为再拿完对象后一般需要把对象重置一下
        //这里提供了一个接口实现，具体是否需要看需求
        // if ("IObjectReset" in item) item.reset();
        return item;
    }

    /**
     * 预加载对象
     */
    private preLoadObj(num: number = this.poolMinSize) {
        let size = num ? num : this.poolMinSize;
        while (this.objCount <= size) {
            let item = new this.objType();
            this.pool.push(item);
            this.objCount++;
            // 如果池内对象数大于最大限制，只加载一个对象退出
            if (this.objCount > this.poolMaxSize) {
                return;
            }
        }
    }

    /**
     * 释放内存
     */
    public releaseAll() {
        this.pool.length = 0;
        this.objCount = 0;
    }
}
